package com.kongjs.application.controller.rest;

import com.kongjs.application.annotation.OperationLogging;
import com.kongjs.application.convert.GroupsConverter;
import com.kongjs.application.enums.OperationName;
import com.kongjs.application.enums.OperationType;
import com.kongjs.application.model.dto.QueryGroupDTO;
import com.kongjs.application.model.dto.QueryGroupParamDTO;
import com.kongjs.application.model.dto.SaveGroupDTO;
import com.kongjs.application.model.dto.UpdateGroupDTO;
import com.kongjs.application.model.vo.QueryGroupParamVO;
import com.kongjs.application.model.vo.QueryGroupVO;
import com.kongjs.application.model.vo.SaveGroupVO;
import com.kongjs.application.model.vo.UpdateGroupVO;
import com.kongjs.application.service.IGroupsService;
import com.kongjs.application.util.TreeUtil;
import com.kongjs.common.rest.annotation.Rest;
import jakarta.annotation.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@Rest
@RestController
@RequestMapping("/groups")
public class GroupsController {
    @Resource
    private GroupsConverter groupsConverter;

    @Resource
    private IGroupsService groupsService;

    @PreAuthorize("hasAuthority('api:group:save:one')")
    @PostMapping
    @OperationLogging(operationName = OperationName.GROUP, operationType = OperationType.SAVE_ONE)
    public boolean save(@RequestBody @Validated SaveGroupVO vo) {
        SaveGroupDTO dto = groupsConverter.toDto(vo);
        return groupsService.save(dto);
    }

    @PreAuthorize("hasAuthority('api:group:remove:one')")
    @DeleteMapping("/{id}")
    @OperationLogging(operationName = OperationName.GROUP, operationType = OperationType.REMOVE_ONE)
    public boolean remove(@PathVariable("id") Long id) {
        return groupsService.remove(id);
    }

    @PreAuthorize("hasAuthority('api:group:update:one')")
    @PutMapping("/{id}")
    @OperationLogging(operationName = OperationName.GROUP, operationType = OperationType.UPDATE_ONE)
    public boolean update(@PathVariable("id") Long id, @RequestBody @Validated UpdateGroupVO vo) {
        UpdateGroupDTO dto = groupsConverter.toDto(vo);
        dto.setId(id);
        return groupsService.update(dto);
    }

    @PreAuthorize("hasAuthority('api:group:update:one')")
    @PatchMapping("/{id}")
    @OperationLogging(operationName = OperationName.GROUP, operationType = OperationType.UPDATE_ONE)
    public boolean updatePart(@PathVariable("id") Long id, @RequestBody UpdateGroupVO vo) {
        UpdateGroupDTO dto = groupsConverter.toDto(vo);
        dto.setId(id);
        return groupsService.update(dto);
    }

    @PreAuthorize("hasAuthority('api:group:query:one')")
    @GetMapping("/{id}")
    @OperationLogging(operationName = OperationName.GROUP, operationType = OperationType.QUERY_ONE, recordResponse = false)
    public QueryGroupVO query(@PathVariable("id") Long id) {
        QueryGroupDTO dto = groupsService.query(id);
        return groupsConverter.toVo(dto);
    }

    @PreAuthorize("hasAuthority('api:group:query:list')")
    @GetMapping
    @OperationLogging(operationName = OperationName.GROUP, operationType = OperationType.QUERY_LIST, recordResponse = false)
    public List<QueryGroupVO> queryList(QueryGroupParamVO vo) {
        QueryGroupParamDTO dto = groupsConverter.toDto(vo);
        List<QueryGroupDTO> dtos = groupsService.querylist(dto);
        List<QueryGroupVO> vos = groupsConverter.toVos(dtos);
        return TreeUtil.buildTree(vos);
    }

    @PreAuthorize("hasAuthority('api:group:query:list') || hasAuthority('api:group:query:tree')")
    @GetMapping("/trees")
    @OperationLogging(operationName = OperationName.GROUP, operationType = OperationType.QUERY_TREE, recordResponse = false)
    public List<QueryGroupVO> trees(QueryGroupParamVO vo) {
        QueryGroupParamDTO dto = groupsConverter.toDto(vo);
        List<QueryGroupDTO> dtos = groupsService.trees(dto);
        List<QueryGroupVO> vos = groupsConverter.toVos(dtos);
        return TreeUtil.buildTree(vos);
    }
}
